package multidraw.model;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Stroke;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
import java.util.Vector;

public class FreehandShape extends Shape implements TwoEndBoundaryShape {
	//protected ArrayList<Point> points;
	protected GeneralPath path;
	
	public FreehandShape(Point initialPoint, Color c, long id) {
		this.shapeID = id;
		penColor = c;		
		//points = new ArrayList<Point>();
		//points.add(initialPoint);
		path = new GeneralPath();
		
		path.moveTo(initialPoint.getX(), initialPoint.getY());
	}
	
	protected FreehandShape(GeneralPath path, Color c) {
		penColor = c;
		//points.addAll(points);
		this.path = (GeneralPath) path.clone();
//		
//		
//		path = new GeneralPath();
//		
//		
//		if (points.size() > 0) {
//			Point initialPoint = points.get(0);
//			path.moveTo(initialPoint.getX(), initialPoint.getY());
//			
//			for (int i = 1; i < points.size(); i++) {
//				Point p = points.get(i);
//				
//				path.lineTo(p.getX(), p.getY());
//			}
//		}
	}
	
	public void draw(Graphics g, boolean selected) {
		// TODO Auto-generated method stub
		Graphics2D g2 = (Graphics2D) g;
		
		Color c = g2.getColor();

		g2.setColor(penColor);

		g2.draw(path);
		
		g2.setColor(c);
	}

	public void drawOutline(Graphics g) {
		// TODO Auto-generated method stub
		Graphics2D g2 = (Graphics2D) g;

	    // highlight the object, draw with dashes line
		

		Stroke oldStroke = g2.getStroke();

		System.out.println("Changing stroke ...");
		g2.setStroke(dashed);

		g2.draw(path);

		// set back the old stroke
		g2.setStroke(oldStroke);
	}

	public boolean isNearControlPoint(Point p) {
		// TODO Auto-generated method stub
		return false;
	}

	public boolean isInsideSelectionalArea(int X, int Y) {
		// TODO Auto-generated method stub
		Rectangle2D selectionalOval = new Rectangle2D.Double(((double)X) - DISTANCE_EPS, 
				((double) Y) - DISTANCE_EPS, DISTANCE_EPS * 2, DISTANCE_EPS * 2);
		System.out.println(selectionalOval);
		System.out.println(path.intersects(selectionalOval));
		return path.intersects(selectionalOval);
	}

	public boolean isInsideBoundaryRectangle(Point p) {
		// TODO Auto-generated method stub
		return path.getBounds2D().contains(p.getX(), p.getY());
	}

	public Shape getOutlineShape() {
		// TODO Auto-generated method stub
		return new FreehandShape(path, penColor);
	}

	public void translate(Point p1, Point p2) {
		// TODO Auto-generated method stub
		AffineTransform transform = new AffineTransform();
		transform.translate(p2.getX() - p1.getX(), p2.getY() - p1.getY());
		path.transform(transform);
	}

	public void updateShapeInfo(Point p1, Point p2) {
		// TODO Auto-generated method stub
		
	}

	public ControlPair getControlPoints(Point p) {
		// TODO Auto-generated method stub
		return null;
	}

	public void addPoint(Point p) {
		//points.add(p);
		path.lineTo(p.getX(), p.getY());
	}
	
	/**
	 * Get control points list: points at 4 corners, clock-wise, starting from leftX, topY
	 * @return
	 */
	protected Vector<Point> getControlPoints() {
		//Get the bounding box
		Rectangle2D boundingBox = path.getBounds2D();
		double leftX = boundingBox.getX();
		double topY = boundingBox.getY();
		double width = boundingBox.getWidth();
		double height = boundingBox.getHeight();
		
		Vector<Point> cl = new Vector<Point>(4, 1);
						
		cl.add(new Point((int)leftX, (int)topY));
		cl.add(new Point((int)(leftX + width), (int)topY));
		cl.add(new Point((int)(leftX + width), (int)(topY + height)));
		cl.add(new Point((int)leftX, (int)(topY + height)));
		return cl;
	}
}
